package net.maku.events.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import lombok.AllArgsConstructor;
import net.maku.events.enums.ActivityQuestionTypeEnum;
import net.maku.events.enums.QuestionType;
import net.maku.events.enums.WhetherPointsEnum;
import net.maku.events.service.UserContestQuestionOptionService;
import net.maku.events.vo.AlreadyAnswerQuestionBankOptionVO;
import net.maku.events.vo.AlreadyAnswerQuestionBankVO;
import net.maku.events.vo.UserAnswerQuestionBankVO;
import net.maku.framework.common.exception.ServerException;
import net.maku.framework.common.utils.DateUtils;
import net.maku.framework.common.utils.PageResult;
import net.maku.framework.mybatis.service.impl.BaseServiceImpl;
import net.maku.events.convert.UserContestQuestionConvert;
import net.maku.events.entity.UserContestQuestionEntity;
import net.maku.events.query.UserContestQuestionQuery;
import net.maku.events.vo.UserContestQuestionVO;
import net.maku.events.dao.UserContestQuestionDao;
import net.maku.events.service.UserContestQuestionService;
import net.maku.framework.security.user.SecurityUser;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户所答竞赛
 *
 * @author 阿沐 babamu@126.com
 * @since 1.0.0 2025-03-22
 */
@Service
@AllArgsConstructor
public class UserContestQuestionServiceImpl extends BaseServiceImpl<UserContestQuestionDao, UserContestQuestionEntity> implements UserContestQuestionService {

    private final UserContestQuestionOptionService userContestQuestionOptionService;

    @Override
    public PageResult<UserContestQuestionVO> page(UserContestQuestionQuery query) {
        IPage<UserContestQuestionEntity> page = baseMapper.selectPage(getPage(query), getWrapper(query));

        return new PageResult<>(UserContestQuestionConvert.INSTANCE.convertList(page.getRecords()), page.getTotal());
    }

    private LambdaQueryWrapper<UserContestQuestionEntity> getWrapper(UserContestQuestionQuery query) {
        LambdaQueryWrapper<UserContestQuestionEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(UserContestQuestionEntity::getUserId, SecurityUser.getUserId());
        return wrapper;
    }

    @Override
    public double save(Long relationId, Long relationSonId, Long businessId, Integer businessType, List<UserAnswerQuestionBankVO> voList) {
        Long userId = SecurityUser.getUserId();
        List<Double> pointsList = new ArrayList<>();
        List<Integer> answerRightList = new ArrayList<>();
        voList.forEach(item -> {
            UserContestQuestionEntity entity = BeanUtil.copyProperties(item, UserContestQuestionEntity.class);
            entity.setUserId(userId);
            entity.setRelationId(relationId);
            entity.setRelationSonId(relationSonId);
            entity.setBusinessId(businessId);
            entity.setContestQuestionId(item.getId());
            entity.setBusinessType(businessType);
            entity.setQuestionType(item.getQuestionType());
            entity.setUserAnswerJudgment(item.getUserAnswerJudgment());
            entity.setId(null);
            baseMapper.insert(entity);
            if (!item.getQuestionType().equals(QuestionType.JUDGMENT.getCode())) {
                boolean flag = userContestQuestionOptionService.save(entity.getId(), item.getActivityContestQuestionOptionList());
                if (flag) {
                    pointsList.add(ObjectUtils.isNotEmpty(item.getObtainedPoints()) ? item.getObtainedPoints() : 0.0);
                    answerRightList.add(WhetherPointsEnum.YES.getType());
                }
            } else {
                if (item.getUserAnswerJudgment().equals(item.getWhetherCorrect())) {
                    pointsList.add(item.getObtainedPoints());
                    answerRightList.add(WhetherPointsEnum.YES.getType());
                }
            }
        });
        if (ActivityQuestionTypeEnum.WALK_ACTIVITY.getBusinessType().equals(businessType)) {
            //则需要判断答对数量是否是题目数量，不是则不会解锁站点
            return answerRightList.size() == voList.size() ? pointsList.stream().reduce(0.0, (a, b) -> a + b) : -1;
        }
        return pointsList.stream().reduce(0.0, (a, b) -> a + b);
    }

    @Override
    public List<Long> getAlreadyAnswerIdList(List<Long> businessIdList, Integer businessType) {
        LambdaQueryWrapper<UserContestQuestionEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(UserContestQuestionEntity::getUserId, SecurityUser.getUserId())
                .eq(UserContestQuestionEntity::getBusinessType, businessType)
                .in(UserContestQuestionEntity::getId, businessIdList);
        List<UserContestQuestionEntity> entityList = this.list(wrapper);
        if (CollectionUtils.isNotEmpty(entityList)) {
            return entityList.stream().map(UserContestQuestionEntity::getBusinessId).collect(Collectors.toList());
        }
        return List.of();
    }

    @Override
    public List<AlreadyAnswerQuestionBankVO> getAlreadyAnswer(Long relationId, Long relationSonId, boolean today, Long businessId, Integer businessType, List<Long> questionIdList) {
        LambdaQueryWrapper<UserContestQuestionEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(UserContestQuestionEntity::getUserId, SecurityUser.getUserId())
                .eq(UserContestQuestionEntity::getBusinessType, businessType)
                .eq(ObjectUtils.isNotEmpty(relationId), UserContestQuestionEntity::getRelationId, relationId)
                .eq(ObjectUtils.isNotEmpty(relationSonId), UserContestQuestionEntity::getRelationSonId, relationSonId)
                .eq(UserContestQuestionEntity::getBusinessId, businessId)
                .in(UserContestQuestionEntity::getContestQuestionId, questionIdList);
        if(today){
            wrapper.apply("date_format(create_time,'%Y-%m-%d') = date_format ({0},'%Y-%m-%d')", DateUtils.format(new Date(), DateUtils.DATE_PATTERN));
        }
        List<UserContestQuestionEntity> entityList = this.list(wrapper);
        if (CollectionUtils.isEmpty(entityList)) {
            throw new ServerException("答题未找到");
        }
        List<AlreadyAnswerQuestionBankVO> questionBankVOList = BeanUtil.copyToList(entityList, AlreadyAnswerQuestionBankVO.class);
        Map<Long, List<AlreadyAnswerQuestionBankOptionVO>> optionMap = userContestQuestionOptionService.getAlreadyAnswerOption(entityList.stream().map(UserContestQuestionEntity::getId).toList());
        if (ObjectUtils.isEmpty(optionMap)) {
            return questionBankVOList;
        }
        questionBankVOList.forEach(item -> {
            item.setActivityContestQuestionOptionList(optionMap.getOrDefault(item.getId(), null));
            item.setId(item.getContestQuestionId());
        });
        return questionBankVOList;
    }

}